package com.ioc.business.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ioc.business.base.domain.CustomerInfo;
import com.ioc.business.base.mapper.CustomerInfoMapper;
import com.ioc.business.order.domain.DeliveryOrder;
import com.ioc.business.order.domain.bo.delivery.DeliveryOrderBo;
import com.ioc.business.order.domain.bo.delivery.DeliveryOrderQueryBo;
import com.ioc.business.order.enums.OrderStatusEnum;
import com.ioc.business.order.mapper.DeliveryOrderMapper;
import com.ioc.business.order.service.IDeliveryOrderService;
import com.ioc.business.order.vo.delivery.DeliveryOrderImportVo;
import com.ioc.business.order.vo.delivery.DeliveryOrderPageVo;
import com.ioc.business.order.vo.delivery.DeliveryOrderVo;
import com.ioc.common.constant.UserConstants;
import com.ioc.common.core.page.TableVo;
import com.ioc.common.exception.ServiceException;
import com.ioc.common.utils.SecurityUtils;
import com.ioc.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 发货订单表 服务实现类
 * </p>
 *
 * @author WeiZhongRong
 * @since 2025-01-07
 */
@Service
@AllArgsConstructor
public class DeliveryOrderServiceImpl extends ServiceImpl<DeliveryOrderMapper, DeliveryOrder> implements IDeliveryOrderService {

    private final CustomerInfoMapper customerInfoMapper;

    @Override
    public TableVo<DeliveryOrder, DeliveryOrderPageVo> selectDeliveryOrderPageList(DeliveryOrderQueryBo queryBo) {
        List<DeliveryOrder> result = baseMapper
                .queryPageList(queryBo);
        List<DeliveryOrderPageVo> pageVos = new ArrayList<>(result.size());
        if (CollectionUtil.isNotEmpty(result)) {
            pageVos = buildPageVos(result);
        }
        return new TableVo<>(result, pageVos);
    }

    private List<DeliveryOrderPageVo> buildPageVos(List<DeliveryOrder> records) {
        return records.stream().map(record -> {
            DeliveryOrderPageVo vo = new DeliveryOrderPageVo();
            BeanUtils.copyProperties(record, vo);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public DeliveryOrderVo selectDeliveryOrderById(Long deliveryOrderId) {
        DeliveryOrder deliveryOrder = getById(deliveryOrderId);
        if (ObjectUtil.isNotEmpty(deliveryOrder)) {
            DeliveryOrderVo deliveryOrderVo = new DeliveryOrderVo();
            BeanUtils.copyProperties(deliveryOrder, deliveryOrderVo);
            return deliveryOrderVo;
        }
        return null;
    }

    /**
     * 新增发货订单
     *
     * @param bo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addDeliveryOrder(DeliveryOrderBo bo) {
        DeliveryOrder deliveryOrder = new DeliveryOrder();
        BeanUtils.copyProperties(bo, deliveryOrder);
        deliveryOrder.setCreateBy(SecurityUtils.getUsername());
        deliveryOrder.setCreateTime(new Date());
        deliveryOrder.setUpdateBy(SecurityUtils.getUsername());
        deliveryOrder.setUpdateTime(deliveryOrder.getCreateTime());
        deliveryOrder.setDelFlag(UserConstants.DEL_FLAG_NORMAL);
        return save(deliveryOrder);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateDeliveryOrder(DeliveryOrderBo bo) {
        DeliveryOrder deliveryOrder = new DeliveryOrder();
        BeanUtils.copyProperties(bo, deliveryOrder);
        deliveryOrder.setUpdateBy(SecurityUtils.getUsername());
        deliveryOrder.setUpdateTime(deliveryOrder.getCreateTime());
        return updateById(deliveryOrder);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeDeliveryOrder(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return false;
        }
        List<DeliveryOrder> updateList = idList.stream().map(id -> {
            DeliveryOrder deliveryOrder = new DeliveryOrder();
            deliveryOrder.setDeliveryOrderId(id);
            deliveryOrder.setDelFlag(UserConstants.DEL_FLAG_REMOVED);
            return deliveryOrder;
        }).collect(Collectors.toList());
        return updateBatchById(updateList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importDeliveryOrder(List<DeliveryOrderImportVo> voList) {
        List<DeliveryOrder> deliveryOrderList = verifyImportData(voList);
        saveBatch(deliveryOrderList);
    }

    private List<DeliveryOrder> verifyImportData(List<DeliveryOrderImportVo> voList) {
        if (CollectionUtil.isEmpty(voList)) {
            throw new ServiceException("导入数据不能为空");
        }
        List<CustomerInfo> list = new LambdaQueryChainWrapper<>(customerInfoMapper)
                .eq(CustomerInfo::getDelFlag, UserConstants.DEL_FLAG_NORMAL)
                .list();
        Map<String, Long> customerNameIdMapMap = CustomerInfo.toNameIdMap(list);
        List<DeliveryOrder> deliveryOrderList = new ArrayList<>(voList.size());
        String username = SecurityUtils.getUsername();
        Date date = new Date();
        for (DeliveryOrderImportVo deliveryOrderImportVo : voList) {
            DeliveryOrder deliveryOrder = new DeliveryOrder();
            BeanUtils.copyProperties(deliveryOrderImportVo, deliveryOrder);
            verifyField(deliveryOrder, deliveryOrderImportVo, customerNameIdMapMap);
            deliveryOrder.setCreateBy(username);
            deliveryOrder.setCreateTime(date);
            deliveryOrder.setUpdateBy(username);
            deliveryOrder.setUpdateTime(date);
            deliveryOrder.setDelFlag(UserConstants.DEL_FLAG_NORMAL);
            deliveryOrderList.add(deliveryOrder);
        }
        return deliveryOrderList;
    }

    private void verifyField(DeliveryOrder deliveryOrder,
                             DeliveryOrderImportVo deliveryOrderImportVo,
                             Map<String, Long> customerNameIdMapMap) {
        if (StrUtil.isBlank(deliveryOrderImportVo.getOrderCode())) {
            throw new ServiceException("收货单号不能为空!");
        }

        String customerName = deliveryOrderImportVo.getCustomerName();
        if (StrUtil.isBlank(customerName)) {
            throw new ServiceException("客户名称不能为空!");
        }
        Long customerId = customerNameIdMapMap.getOrDefault(customerName, null);
        if (ObjectUtil.isEmpty(customerId)) {
            throw new ServiceException("客户名称【" + customerName + "】不存在!");
        }
        deliveryOrder.setCustomerId(customerId);
        deliveryOrder.setCustomerName(customerName);

        String deliveryTimeStr = deliveryOrderImportVo.getDeliveryTime();
        Date deliveryTime = null;
        try {
            deliveryTime = StrUtil.isNotBlank(deliveryTimeStr) ? DateUtil.parse(deliveryTimeStr) : null;
        } catch (Exception e) {
            throw new ServiceException("发货时间格式不正确!");
        }
        deliveryOrder.setDeliveryTime(deliveryTime);

        String estimatedFinishTimeStr = deliveryOrderImportVo.getEstimatedFinishTime();
        Date estimatedFinishTime = null;
        try {
            estimatedFinishTime = StrUtil.isNotBlank(estimatedFinishTimeStr) ? DateUtil.parse(estimatedFinishTimeStr) : null;
        } catch (Exception e) {
            throw new ServiceException("预计完成时间格式不正确!");
        }
        deliveryOrder.setEstimatedFinishTime(estimatedFinishTime);
        deliveryOrder.setTaskProgress(StringUtils.numberStrToPercentStr(deliveryOrder.getTaskProgress()));

        OrderStatusEnum deliveryStatus = OrderStatusEnum.NORMAL;
        String deliveryStatusStr = deliveryOrderImportVo.getDeliveryStatus();
        if (StrUtil.isNotBlank(deliveryStatusStr)) {
            OrderStatusEnum statusEnum = OrderStatusEnum.getByDesc(deliveryStatusStr);
            if (ObjectUtil.isEmpty(statusEnum)) {
                throw new ServiceException("发货状态【" + deliveryStatusStr + "】不存在!");
            }
            deliveryStatus = statusEnum;
        }
        deliveryOrder.setDeliveryStatus(deliveryStatus);

        OrderStatusEnum transportStatus = OrderStatusEnum.NORMAL;
        String transportStatusStr = deliveryOrderImportVo.getTransportStatus();
        if (StrUtil.isNotBlank(transportStatusStr)) {
            OrderStatusEnum statusEnum = OrderStatusEnum.getByDesc(transportStatusStr);
            if (ObjectUtil.isEmpty(statusEnum)) {
                throw new ServiceException("运输状态【" + deliveryStatusStr + "】不存在!");
            }
            transportStatus = statusEnum;
        }
        deliveryOrder.setTransportStatus(transportStatus);
    }
}
